package org.leviatan.definator.core;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class DefinatorConfiguration {
	
	
	private Properties props			= new Properties();
	
	private FileInputStream fis			= null;
	private BufferedInputStream bis		= null;
	
	private FileOutputStream fos 		= null;
	private BufferedOutputStream bos	= null;
	
	Logger logger = Logger.getLogger(DefinatorConfiguration.class);
	
	
	public String confFilePath;
	
	
	public String confPath;
	public String homePath;
	public String regPath;
	public String serPath;
	
	public String logginLevel;
	
	public String logConfFileName;
	public String tblRegFileName;
	public String recRegFileName;
	public String fldRegFileName;
	
	public String logConfFullPathName;
	
	
	private DefinatorConfiguration() {
		
	}
	
	
	public static DefinatorConfiguration factorNewConfiguration(String filePath) {
		DefinatorConfiguration defConf = new DefinatorConfiguration();
		defConf.confFilePath = filePath;
		
		// load props!!!
		defConf.readConfiguration();
		
		return defConf;
	}
	
	public void saveConfigurationOnFile() {
		try {
			fos = new FileOutputStream(this.confFilePath);
		} catch (FileNotFoundException e) {
			logger.error("Trying to save configuration to file and configuration file not found! Should be placed in /conf/");
			e.printStackTrace();
		}
		
		bos = new BufferedOutputStream(fos);
		
		try {
			props.store(bos, "Definator Configuration File");
		} catch (IOException e) {
			logger.error("IOException when trying to write configuration to file!");
			e.printStackTrace();
		}
	}

	public void readConfiguration() {
		
		try {
			fis = new FileInputStream(this.confFilePath);
		} catch (FileNotFoundException e) {
			logger.error("Definator configuration file not found! Should be placed in /conf/");
			e.printStackTrace();
		}
		bis = new BufferedInputStream(fis);
		
		try {
			props.load(bis);
		} catch (IOException e) {
			logger.error("Couldn't load configuration!");
			e.printStackTrace();
		}
		
		try 
		{
			bis.close();
		} catch (IOException e) {
			logger.warn("Couldn't close buffered output stream!");
			e.printStackTrace();
		}
		try {
			fis.close();
		} catch (IOException e) {
			logger.warn("Couldn't close file output stream!");
			e.printStackTrace();
		}
		
		// load props into variables
		homePath 		= props.getProperty("home-path");
		confPath 		= props.getProperty("conf-path");
		regPath 		= props.getProperty("registry-path");
		serPath			= props.getProperty("ser-path");
		
		logConfFileName = props.getProperty("logging-conf-file-name");
		logginLevel 	= props.getProperty("logging-level");
		
		
		tblRegFileName	= props.getProperty("tbl-reg-file-name");
		recRegFileName	= props.getProperty("rec-reg-file-name");
		fldRegFileName	= props.getProperty("fld-reg-file-name");
		
		logConfFullPathName = confPath + logConfFileName;
		
		// setup logger
		DOMConfigurator.configure(confPath + logConfFileName);
		
		logger.info("Loaded configurations.");
	}
	
	public Properties getProperties() {
		return props;
	}
	
	public void setProperty(String key, Object prop) {
		props.put(key, prop);
	}
	
	
	protected void finalize() throws Throwable {
		super.finalize();
		try 
		{
			bis.close();
		} catch (IOException e) {
			logger.warn("Couldn't close buffered input stream!");
			e.printStackTrace();
		}
		try {
			fis.close();
		} catch (IOException e) {
			logger.warn("Couldn't close file input stream!");
			e.printStackTrace();
		}
		try {
			bos.close();
		} catch (IOException e) {
			logger.warn("Couldn't close buffered output stream!");
		}
		try {
			fos.close();
		} catch (IOException e) {
			logger.warn("Couldn't close file output stream!");
		}	
	}
	
}
